module ActsAsAspdotnet::RoutingOverrides
  
  # OVERRIDE
  def resources(*entities, &block)
    generate_aspdotnet_routes_for_resources(self, entities)
    super(entities, &block)
  end

  def resource(*entities, &block)
    generate_aspdotnet_routes_for_resources(self, entities)
    super(entities, &block)
  end
  
  # Added some additional routes around the boring Rails ones
  def generate_aspdotnet_routes_for_resources(map, *entities)

    # format name
    resource_name = entities.flatten.first.to_s.downcase # => item or items
    resource_single = resource_name.singularize # => item  

    # format title
    resource_title = resource_name.capitalize # => Item or Items
    resource_title_single = resource_title.singularize # => Item

    # puts "OVERRIDING RESOURCE: #{resource_name}"
    
    # build routes for resource
    with_options(:controller => resource_name) do |m|
      
      # remap index action
      # map.aspdotnet_items "/Items/Default.aspx", :action => "index", :conditions => {:method => :get}
      m.send :"aspdotnet_#{resource_name}", "/#{resource_title}/Default.aspx", :action => "index", :conditions => {:method => :get}
    
      # remap create action
      # map.connect "/Items/Default.aspx", :action => "create", :conditions => {:method => :post}
      m.connect "/#{resource_title}/Default.aspx", :action => "create", :conditions => {:method => :post}
      
      # remap update action
      # map.connect "/Items/:id/Show.aspx", :action => "update", :conditions => {:method => :get}
      m.connect "/#{resource_title}/:id/Show.aspx", :action => "update", :conditions => {:method => :put}

      # remap destroy action (with the same show_url)
      # map.connect "/Items/:id/Show.aspx", :action => "destroy", :conditions => {:method => :delete}
      m.connect "/#{resource_title}/:id/Show.aspx", :action => "destroy", :conditions => {:method => :delete}

      # remap show action
      # map.aspdotnet_item "/Items/:id/Show.aspx", :action => "show", :conditions => {:method => :get}
      m.send :"aspdotnet_#{resource_single}", "/#{resource_title}/:id/Show.aspx", :action => "show", :conditions => {:method => :get}
      
      # remap new action
      # map.aspdotnet_new_item "/Items/:id/New.aspx", :action => "new"
      m.send :"aspdotnet_new_#{resource_single}", "/#{resource_title}/New.aspx", :action => "new", :conditions => {:method => :get}
      
      # remap edit action
      # map.aspdotnet_edit_item "/Items/:id/Edit.aspx", :action => "edit"
      m.send :"aspdotnet_edit_#{resource_single}", "/#{resource_title}/:id/Edit.aspx", :action => "edit", :conditions => {:method => :get}
    end
          
    # generate helper methods
    
    # Wrap Index Helper: items_url
    # build_helper_wrapper(:items_url, :aspdotnet_items_url)
    build_helper_wrapper(:"#{resource_name}_url", :"aspdotnet_#{resource_name}_url")
    build_helper_wrapper(:"#{resource_name}_path", :"aspdotnet_#{resource_name}_path")
    
    # Wrap New Helper: new_item_url
    # build_helper_wrapper(:new_item_url, :aspdotnet_new_item_url, true)
    build_helper_wrapper(:"new_#{resource_single}_url", :"aspdotnet_new_#{resource_single}_url")
    build_helper_wrapper(:"new_#{resource_single}_path", :"aspdotnet_new_#{resource_single}_path")
          
    
    # Wrap Show Helper: item_url
    # build_helper_wrapper(:item_url, :aspdotnet_item_url, true)
    build_helper_wrapper_with_record(:"#{resource_single}_url", :"aspdotnet_#{resource_single}_url")
    build_helper_wrapper_with_record(:"#{resource_single}_path", :"aspdotnet_#{resource_single}_path")
    
    # Wrap Edit Helper: edit_item_url
    # build_helper_wrapper(:edit_item_url, :aspdotnet_edit_item_url, true)
    build_helper_wrapper_with_record(:"edit_#{resource_single}_url", :"aspdotnet_edit_#{resource_single}_url")
    build_helper_wrapper_with_record(:"edit_#{resource_single}_path", :"aspdotnet_edit_#{resource_single}_path")
  end
  
  # SINGULAR RESOURCE
  def generate_aspdotnet_routes_for_resource(map, *entities)
    resource_name = entities.flatten.first
  end

  # Defines 2 helper methods on ActionView::Base that wrap around a resource:
  # ---
  # def items_url
  #   aspdotnet_items_url
  # end
  # ---
  def build_helper_wrapper(old_name, new_name, pass_record = false)
    wrapper_method = %(
      def #{old_name}
        #{new_name}
      end
    )

    # create the helper method
    ActionView::Base.class_eval wrapper_method, __FILE__, __LINE__
  end
  
  # Defines 2 helper methods on ActionView::Base that wrap around a resource (taking in a record)
  # def item_url(record)
  #   aspdotnet_item_url(:id => record)
  # end
  def build_helper_wrapper_with_record(old_name, new_name)
    wrapper_method = %(
      def #{old_name}(record)
        #{new_name}(:id => record)
      end
    )
    # create the helper method
    ActionView::Base.class_eval wrapper_method, __FILE__, __LINE__
  end
end
